﻿using System;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using AdTech.Common;

namespace AdTech.Snap
{
    /// <summary>
    /// Holds serializable configuration properties and loads/saves them from/to file.
    /// </summary>
    [XmlRootAttribute(ElementName = "Settings", IsNullable = false)]
    public class DefaultConfiguration : SerializableClass<DefaultConfiguration>, IConfiguration
    {
        /// <summary>
        /// Gets the path to the configuration file.
        /// </summary>
        protected static string FilePath { get; private set; }

        /// <summary>
        /// Gets a value whether this is a new configuration.
        /// </summary>
        [XmlIgnore]
        public bool IsNew { get; internal set; }
        /// <summary>
        /// Gets a value whether Snap is in AutoStart.
        /// </summary>
        [XmlIgnore]
        public bool IsInSystemStart { get { return AutoStart.IsAutoStartEnabled("Snap", Assembly.GetExecutingAssembly().Location); } }
        #region Serialization Properties
        /// <summary>
        /// Gets or sets the color of the overlay when cropping screenshots.
        /// </summary>
        public string OverlayColor { get; set; }
        /// <summary>
        /// Gets or sets the opacity of the overlay when cropping screenshots.
        /// </summary>
        public double OverlayColorOpacity { get; set; }
        /// <summary>
        /// Gets or sets the default destination for screenshots.
        /// If set, the filenames will be generated uniquely.
        /// If set to null or empty a dialog will prompt the user to select a destination.
        /// </summary>
        public string DefaultFileDestination { get; set; }
        /// <summary>
        /// Gets or sets a value whether to use dropbox integration.
        /// This requires that the DefaultFileDestination property is set and pointing at the public Dropbox folder.
        /// If set to true, a public link will be copied to the clipboard afterwards.
        /// </summary>
        public bool UseDropbox { get; set; }
        /// <summary>
        /// Gets or sets a value whether a QRCode of the public Dropbox link should be created.
        /// This requires the Dropbox integration to be enabled.
        /// </summary>
        public bool CreateQRCode { get; set; }
        /// <summary>
        /// Gets or sets the Dropbox UserID which is required to generate a public link and copy it to the clipboard.
        /// </summary>
        public int DropboxUID { get; set; }
        #endregion

        // Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="AdTech.Snap.DefaultConfiguration"/> class.
        /// </summary>
        public DefaultConfiguration()
        {
        }
        static DefaultConfiguration()
        {
            FilePath = String.Format("{0}{1}{2}{1}{3}{1}{4}", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Path.DirectorySeparatorChar, "AdTech", "Snap", "Settings.xml");
        }

        // Initialization Methods
        /// <summary>
        /// Creates an empty configuration instance.
        /// </summary>
        public static IConfiguration Create()
        {
            IConfiguration cfg = new DefaultConfiguration();
            return cfg;
        }
        /// <summary>
        /// Creates a default configuration instance.
        /// </summary>
        public static IConfiguration Default()
        {
            IConfiguration cfg = Create();
            cfg.OverlayColor = "Black";
            cfg.OverlayColorOpacity = 0.6;
            return cfg;
        }
        /// <summary>
        /// Loads the settings and returns a new configuration instance.
        /// </summary>
        public static IConfiguration Load()
        {
            DefaultConfiguration cfg;
            if (File.Exists(FilePath))
                cfg = Load(FilePath);
            else
            {
                cfg = (DefaultConfiguration)Default();
                cfg.IsNew = true;
            }
            return cfg;
        }

        #region IConfiguration Members
        /// <summary>
        /// Saves the current configuration instance.
        /// </summary>
        public void Save()
        {
            this.Save(FilePath);
        }

        /// <summary>
        /// Returns a shallow copy of the current configuration instance.
        /// </summary>
        /// <returns>A new <see cref="AdTech.Snap.IConfiguration"/> instance with the same values.</returns>
        public IConfiguration Clone()
        {
            return (IConfiguration)this.MemberwiseClone();
        }

        /// <summary>
        /// Copies the given configuration instance properties to those of the current one but keeps the object reference.
        /// </summary>
        /// <param name="source">An <see cref="AdTech.Snap.IConfiguration"/> instance to copy properties from.</param>
        public void MapFrom(IConfiguration source)
        {
            this.IsNew = source.IsNew;
            this.DefaultFileDestination = source.DefaultFileDestination;
            this.DropboxUID = source.DropboxUID;
            this.OverlayColor = source.OverlayColor;
            this.OverlayColorOpacity = source.OverlayColorOpacity;
            this.UseDropbox = source.UseDropbox;
            this.CreateQRCode = source.CreateQRCode;
        }
        
        /// <summary>
        /// Adds or removes Snap from AutoStart.
        /// </summary>
        /// <param name="value">Set to true if it should be added to AutoStart or false if it should be removed.</param>
        public void SetAutostart(bool value)
        {
            if (value)
                AutoStart.SetAutoStart("Snap", Assembly.GetExecutingAssembly().Location);
            else
                AutoStart.UnsetAutoStart("Snap");
        }
        #endregion
    }
}
